/*
 * cvEyeDetector.c
 *
 *  Created on: Feb 13, 2010
 *      Author: nicolas
 */

// Include header files
#include "cv.h"
#include "highgui.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <float.h>
#include <limits.h>
#include <time.h>
#include <ctype.h>

// Create memory for calculations
static CvMemStorage* storage = 0;
static CvHaarClassifierCascade* cascade_f;
static CvHaarClassifierCascade* cascade_e;
static IplImage* image;

// Create a string that contains the cascade name
const char* cascade_f_name;
const char* cascade_e_name;

void detectEyes();

// Main function, defines the entry point for the program.
int main(int argc, char** argv) {

	// Load the face HaarClassifierCascade
	cascade_f_name = argv[1];
	cascade_f = (CvHaarClassifierCascade*) cvLoad(cascade_f_name, 0, 0, 0);
	// Check whether the cascade has loaded successfully. Else report and error and quit
	if (!cascade_f) {
		fprintf(stderr, "ERROR: Could not load classifier cascade\n");
		return -1;
	}

	// Load the eye HaarClassifierCascade
	cascade_e_name = argv[2];
	cascade_e = (CvHaarClassifierCascade*) cvLoad(cascade_e_name, 0, 0, 0);
	// Check whether the cascade has loaded successfully. Else report and error and quit
	if (!cascade_e) {
		fprintf(stderr, "ERROR: Could not load classifier cascade\n");
		return -1;
	}

	// Allocate the memory storage
	storage = cvCreateMemStorage(0);

	const char* filename = argv[3];

	// Load the image from that filename
	image = cvLoadImage(filename, 1);

	// If Image is loaded succesfully, then:
	if (image) {

		detectEyes();

		// Release the image memory
		cvReleaseImage(&image);

		// return 0 to indicate successfull execution of the program
		return 0;
	} else {
		return 1;
	}

}

void detectEyes() {

	/* detect faces */
	CvSeq *faces = cvHaarDetectObjects(image, /* the source image */
	cascade_f, /* the face classifier */
	storage, /* memory buffer, created with cvMemStorage */
	1.1, 3, 0, /* special parameters, tune for your app */
	cvSize(40, 40) /* minimum detection scale */
	);

	/* return if not found */
	if (faces->total == 0)
		return;

	/* get the first detected face */
	CvRect *face = (CvRect*) cvGetSeqElem(faces, 0);

	printf("%i,%i,%i,%i\n", face->x, face->y, face->x + face->width, face->y + face->height);

	int face_x = face->x;
	int face_y = face->y;
	int face_height = face->height;

	/* reset buffer for the next object detection */
	cvClearMemStorage(storage);

	/* Set the Region of Interest: estimate the eyes' position */
	cvSetImageROI(image, /* the source image */
	cvRect(face->x, /* x = start from leftmost */
	face->y + (face->height / 5.5), /* y = a few pixels from the top */
	face->width, /* width = same width with the face */
	face->height / 3.0 /* height = 1/3 of face height */
	));

	/* detect the eyes */
	CvSeq *eyes = cvHaarDetectObjects(image, /* the source image, with the estimated location defined */
	cascade_e, storage, /* memory buffer */
	1.15, 3, 0, /* tune for your app */
	cvSize(25, 15) /* minimum detection scale */
	);

	int i;

	/* print the coordinates for each detected eye */
	for (i = 0; i < (eyes ? eyes->total : 0); i++) {
		/* get one eye */
		CvRect *eye = (CvRect*) cvGetSeqElem(eyes, i);
		printf("%i,%i,%i,%i\n", 
			face_x + eye->x, 
			(int) (face_y + (face_height / 5.5) + eye->y), 
			face_x + eye->x + eye->width,
			(int) (face_y + (face_height / 5.5) + eye->y + eye->height));
	}

}
